/* MapDataVisualization.pde
 *  Use the controls on the right to interact with the map and rollover columns to see data.
 *  Regarding how the data has been defined,the cities in our database refers to integrated 
 *  metropolitan areas rather than specific city jurisdictions ,that is,neighbouring cities 
 *  have been integrated into a single urban center.
 *  
 */

/*******************************
 *     GLOBALS & OBJECTS
 ******************************/
////////////////////////////////////////////////////////////////////////////////////////
int LINE_SPACING = 30;         /* Display line spacing */
int digits = 0;                /* Number of digits for datum */
int coin_x = 15;
int coin_y;

String gdp,
      inflation,
      unemployment,
      govdebt,
      govrev;

int X,Y;
final int
TEXT_COL      = 0xaa000000,
DATA_COL      = #41774e,
HOVER_COL     = #d2f2cc,
WORLD_TINT    = 0xffffffff,
LINES_WEIGHT  = 4,
BUFF_LINES_W  = 6;
float a,b;
PGraphics bg, hover;
PImage bg_img, coin, timeline, dollar_sign;
PFont h0,h1,h2,h3;

int normal_col = TEXT_COL;
int hovered_col = #fcffaa;

// Objects
Globe w;
Table t;
DataHolder[] data;
////////////////////////////////////////////////////////////////////////////////////////

/*********************************
 * MAIN PROCESSING SETUP AND LOOP
 *********************************/
void setup(){
  //Buffers
  size(1100,700,P3D); 
  // Image  buffers
  bg= createGraphics(width,height, P2D);    //Buffer for storing the background
  bg_img = loadImage("bg.png");
  coin = loadImage("coin.png");
  timeline = loadImage("timeline.png");
  dollar_sign = loadImage("dollar_sign.png");
  hover =  createGraphics(width,height,P3D); // Color picking buffer
  smooth();

  //Fonts
  h1= loadFont("MaiandraGD-Regular-34.vlw");
  h2= loadFont("MaiandraGD-Regular-24.vlw");
  h3= loadFont("MaiandraGD-Regular-18.vlw");
  
  //General scene settings
  coin_y = height-100;
  X= width/3;
  Y= height/2;
  createBackground (bg,X,Y,.1);
  frameRate(30);
  cursor(CROSS);
  textMode(SCREEN);

  //Objects
  w= new Globe( 180, 100, "world_day.png");
  t= new Table("5catergories.csv");
  data= new DataHolder[t.getNumRows()-1];
  
  // Load the data
  for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 14);
}

void draw(){
  
  // setup light. to do correct lighting you need to set it before any world transformations
  background(bg);
  image(bg_img, 0, 0, width, height);
  hover.beginDraw(); hover.background(0); hover.endDraw();
  lights();
  w.update();
  render(X,Y); 
  drawTimeLine();
  drawDollarSign();
  detectHover();
  
}

/*********************************
 *    GRAPHICS & RENDERING
 *********************************/
void createBackground (PGraphics pg, int X, int Y,float f){ 
    int x,y;
    pg.beginDraw();
    pg.smooth();
    for(int i=0;++i<pg.width*pg.height;) 
     {pg.set (x=i%pg.width, y=i/pg.width, (255-round(dist(x,y,X,Y)*f))*0x010101);}
    pg.endDraw();
    background(pg);
}

void render(int x, int y){
  hover.beginDraw();
  pushMatrix();
    translate(x,y);
    hover.translate(x,y);
    pushMatrix();
      rotateX(w.rotation.x);
      rotateY(w.rotation.y);
      hover.rotateX(w.rotation.x);
      hover.rotateY(w.rotation.y);
      fill(WORLD_TINT);
      w.render();
      for (int i=0;i<data.length;i++){
          data[i].render(g,false);
          data[i].render(hover,true);
      }
    popMatrix();
  popMatrix();
  hover.endDraw();
}

/* 
 * printData:
 *  - Takes in an index value of the hovered datum,
 *     and displays all other information about the
 *     particular indexed country.
 */
void printData(int index) {
  
  for(int i=0;i<data.length;i++){
    if (i==index) {
      data[i].setHoveredTo(true);
      fill(TEXT_COL);
      
      /* 
       * HACK NOTE (please fix when possible): The following fix is a 
       * hack and should be handled approprately when time allows. 
       * For now, this saves us time to work on other tasks with 
       * higher priority.
       *
       * Country Names on our Spread Sheet have a space at the beggning.
       * This is a minor data-specific bug that I quickly fixed by
       * setting the x index in text() to be about 594 pixels.
       *
       * ~Federico
      */    
      
      // cache strings
      gdp = nf(data[i].GDP, 0, digits);
      inflation = nf(data[i].INFLATION, 0, digits);
      unemployment = nf(data[i].UNEMPLOYMENT, 0, digits);
      govdebt = nf(data[i].GOVDEBT, 0, digits);
      govrev = nf(data[i].GOVREV, 0, digits);
      
      textFont(h1);
      text(data[i].COUNTRY,600, 70);
      
      textFont(h2);
      // If the data includes a -1, it is not available for that year
      if ( data[i].GDP > 0 ) {
        text("GDP (In Billions): "+gdp,610, 75 + LINE_SPACING);
      } else  text("GDP (In Billions): "+"n/a",610, 75 + LINE_SPACING);
      
      if ( data[i].INFLATION > 0 ) {
        text("Inflation Rate: "+inflation,610, 75 + LINE_SPACING*2);
      } else text("Inflation Rate: "+"n/a",610, 75 + LINE_SPACING*2);
      
      if ( data[i].UNEMPLOYMENT > 0 ) {
        text("Unemployment Rate: "+unemployment,610, 75 + LINE_SPACING*3);
      } else text("Unemployment Rate: "+"n/a",610, 75 + LINE_SPACING*3);
      
      if ( data[i].GOVDEBT > 0 ) {
        text("General Government Gross Debt: "+govdebt,610, 75 + LINE_SPACING*4);
      } else  text("General Government Gross Debt: "+"n/a",610, 75 + LINE_SPACING*4);
      
      if ( data[i].GOVREV > 0 ) {
        text("General Government Revenue: "+govrev,610, 75 + LINE_SPACING*5);
      } else text("General Government Revenue: "+"n/a",610, 75 + LINE_SPACING*5);

      noFill();
    }else{
      data[i].setHoveredTo(false);}
  } 
}


/***
 * drawTimeLine: 
 *   - Dsiplays timeline graphics.
 *   - The position of the coin "knob"
 *      is handled in mouseDragged
 **************/
void drawTimeLine () {
    noStroke();
    fill(226, 246, 179, 50);
    rect(0, height - 120, width, 120);
    image(timeline, 0, height - 100);
    image(coin, coin_x, coin_y);
}


/*
 * drawDollarSign:
 */
void drawDollarSign() {
    noStroke();
    image(dollar_sign, 800, 350);
    textFont(h3);
    fill(normal_col);
    
    if ( (mouseX > 800 && mouseX < 870) && (mouseY > 300 && mouseY < 350 ) ) {
       fill(hovered_col);
       text("GDP", 820, 320);
       textFont(h1);
       fill(normal_col);
       text("Gross Domestic Product:", 610, 75);
       textFont(h2);
       text("Values are based upon GDP in national", 610, 75 + LINE_SPACING);
       text("currency converted to U.S. dollars", 610, 75 + LINE_SPACING*2);
       text("using market exchange rates (yearly average).", 610, 75 + LINE_SPACING*3);
       text("Unit : U.S. dollars, Scale : Billions.", 610, 75 + LINE_SPACING*4);
       // reset fonts
       textFont(h3);
       fill(normal_col);
    } else { text("GDP", 820, 320);}
    
    if ( (mouseX > 680 && mouseX < 775) && (mouseY > 355 && mouseY < 380 ) ) {
       fill(hovered_col);
       text("Inflation", 700, 365);
       textFont(h1);
       fill(normal_col);
       text("Inflation:", 610, 75);
       textFont(h2);
       text("Annual percentages of average consumer", 610, 75 + LINE_SPACING);
       text("prices are year-on-year changes.", 610, 75 + LINE_SPACING*2);
       text("Unit : Percentage Change", 610, 75 + LINE_SPACING*3);
       // reset fonts
       textFont(h3);
       fill(normal_col);
    } else { text("Inflation", 700, 365);}
    
    if ( (mouseX > 880 && mouseX < 975) && (mouseY > 350 && mouseY < 380 ) ) {
       fill(hovered_col);
       text("Unemployment", 900, 365);
       textFont(h1);
       fill(normal_col);
       text("Unemployment:", 610, 75);
       textFont(h2);
       text("(Percent of total labor force.)", 610, 75 + LINE_SPACING);
       text("Unemployment rate gives the number of", 610, 75 + LINE_SPACING*2);
       text("unemployed persons as a percentage", 610, 75 + LINE_SPACING*3);
       text("of the labor force", 610, 75 + LINE_SPACING*4);
       // reset fonts
       textFont(h3);
       fill(normal_col);
    } else { text("Unemployment", 900, 365);}
    
    if ( (mouseX > 650 && mouseX < 800) && (mouseY > 490 && mouseY < 525 ) ) {
       fill(hovered_col);
       text("Government Debt", 660, 510);
       textFont(h1);
       fill(normal_col);
       text("General Govt. Gross Debt:", 610, 75);
       textFont(h2);
       text("Gross debt consists of all liabilities", 610, 75 + LINE_SPACING);
       text("that require payment or payments of interest", 610, 75 + LINE_SPACING*2);
       text("and/or principal by the debtor to the creditor", 610, 75 + LINE_SPACING*3);
       text("at a date or dates in the future", 610, 75 + LINE_SPACING*4);
       text("Unit :Percent of GDP", 610, 75 + LINE_SPACING*5);
       // reset fonts
       textFont(h3);
       fill(normal_col);
    } else { text("Government Debt", 660, 510);}
    
    if ( (mouseX > 860 && mouseX < 1100) && (mouseY > 490 && mouseY < 525 ) ) {
       fill(hovered_col);
       text("Government Revenue", 875, 510);
       textFont(h1);
       fill(normal_col);
       text("General Govt. Gross Revenue:", 610, 75);
       textFont(h2);
       text("Consists of taxes, social contributions,", 610, 75 + LINE_SPACING);
       text("grants receivable, and other revenue.", 610, 75 + LINE_SPACING*2);
       text("Revenue increases government?s net worth,", 610, 75 + LINE_SPACING*3);
       text("which is the difference between its assets", 610, 75 + LINE_SPACING*4);
       text("and liabilities.", 610, 75 + LINE_SPACING*5);
       text("Unit: Percent of GDP", 610, 75 + LINE_SPACING*6);
       // reset fonts
       textFont(h3);
       fill(normal_col);
    } else {     text("Government Revenue", 875, 510);}
    
}

/*******************************
 * MOUSE INTERACTIONS FUNCTIONS
 ******************************/
/* 
 * mousePressed:
 *  - Stop the globe whenuser clicks on the Globe. 
 */
void mousePressed() {
  if (mouseButton==LEFT) w.stopRotation();
}

/* 
 * mouseDragged:
 *  - Adds velocity to the world when user drags mouse near it.
 *  - Handles Timeline interaction.
 */
void mouseDragged(){
  if ( mouseY < height - 120 && mouseX < 550 ) {
    if (mouseButton==LEFT)  w.addRotation(mouseX,mouseY,pmouseX,pmouseY);
  }
  else if ( mouseY > height - 120 && (mouseX > 15 && mouseX < 1030) ) {
    // slider handling
    
    /* 
     * Probably not the most efficient way to get this done, but time limitations
     * require us to hard code the timeline pixel valies to correlate to the years.
     *
     */
    coin_x = mouseX;
    
    if ( mouseX > 16 && mouseX < 31 )  {
        coin_x = 18; // snap to point in timeline
        // Load data  
        for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 14); // 1990
    }
    
     else if ( mouseX > 31 && mouseX < 74 ) {
      coin_x = 54;
      for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 15); // 1991
    }
    
     else if ( mouseX > 74 && mouseX < 117 ) {
       coin_x = 102;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 16); // 1992
    }
    
    else if ( mouseX > 117 && mouseX < 160 ) {
      coin_x = 140;
      for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 17); // 1993
    }
    
    else  if ( mouseX > 160  && mouseX <  203) {
       coin_x = 183;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 18); // 1994
    }
    
    else if ( mouseX > 203 && mouseX < 240 ) {
       coin_x = 222;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 19); // 1995
    }
    
    else if ( mouseX > 240 && mouseX < 280 ) {
       coin_x = 265;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 20); // 1996
    }
    
    else if ( mouseX > 280 && mouseX < 322 ) {
       coin_x = 299;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 21); // 1997
    }
    
    else  if ( mouseX > 322 && mouseX < 362 ) {
       coin_x = 346;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 22); // 1998
    }
    
     else if ( mouseX > 362 && mouseX < 405 ) {
       coin_x = 384;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 23); // 1999
    }
    
    else if ( mouseX > 405 && mouseX < 444 ) {
       coin_x = 428;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 24); // 2000
    }
    
    else if ( mouseX > 444 && mouseX < 490 ) {
       coin_x = 466;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 25); // 2001
    }
    
     else if ( mouseX > 490 && mouseX < 530 ) {
       coin_x = 513;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 26); // 2002
    }
    
    else if ( mouseX > 530 && mouseX < 575 ) {
       coin_x = 551;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 27); // 2003
    }
    
    else if ( mouseX > 575 && mouseX < 617 ) {
       coin_x = 601;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 28); // 2004
    }
    
    else if ( mouseX > 617 && mouseX < 658 ) {
       coin_x = 638;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 29); // 2005
    }
    
    else if ( mouseX > 658 && mouseX < 699 ) {
       coin_x = 680;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 30); // 2006
    }
    
    else if ( mouseX > 699 && mouseX < 741 ) {
       coin_x = 716;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 31); // 2007
    }
    
    else if ( mouseX > 741 && mouseX < 785 ) {
       coin_x = 767;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 32); // 2008
    }
    
    else if ( mouseX > 785 && mouseX < 830 ) {
       coin_x = 804;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 33); // 2009
    }
    
    else if ( mouseX > 830 && mouseX < 876 ) {
       coin_x = 858;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 34); // 2010
    }
    
    else if ( mouseX > 876 && mouseX < 915 ) {
       coin_x = 896;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 35); // 2011
    }
    
    else if ( mouseX > 915 && mouseX < 962 ) {
       coin_x = 945;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 36); // 2012
    }
    
    else if ( mouseX > 962 && mouseX < 1005 ) {
       coin_x = 983;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 37); // 2013
    }
    
    else if ( mouseX > 1005 && mouseX < 1100 ) {
       coin_x = 1029;
       for(int i=0;i<data.length;i++) data[i]= new DataHolder(i, 38); // 2014
    }
    
    
    
    
    
  }
}

/* 
 * detectHover:
 *  - Detect when a user hovers over a datum bar
 */
void detectHover(){
  int c=hover.get(mouseX,mouseY);
  int index= c/0x010101 + 254;
  printData(index);
}

/* 
 * keyPressed:
 *  - Keyboard key funtionality:
       1) Saves a screen shot when user presses 's'
       2)
    - TODO: Timeline handling ??
 */
void keyPressed(){
  if (key =='s') // if the s key is pressed
    save("savedimage" + ".jpg"); // save an image screenshot
 
//  if (keyCode == RIGHT){
//    if (selYear == numCols-2) selYear = 1;
//    else if (selYear < numCols-2) selYear = selYear+1;  //when moving right don't go further than num years
//  }
//  else if (keyCode == LEFT){                //when moving left don't go further than first year
//    if (selYear == 1) selYear = numCols-2;
//    else if (selYear > 1) selYear = selYear -1;
//  }
}




